home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / DXTex / dxtex.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  13.3 KB  |  481 lines

  1. // dxtex.cpp : Defines the class behaviors for the application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "dxtex.h"
  6.  
  7. #include "MainFrm.h"
  8. #include "ChildFrm.h"
  9. #include "dxtexDoc.h"
  10. #include "dxtexView.h"
  11.  
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18.  
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CDxtexDocManager::DoPromptFileName - overridden to allow importing of
  22. // BMPs as well as DDSs into CDxtexDocs.
  23. BOOL CDxtexDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle,
  24.             DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
  25. {
  26.     CFileDialog dlgFile(bOpenFileDialog);
  27.  
  28.     CString title;
  29.     VERIFY(title.LoadString(nIDSTitle));
  30.  
  31.     dlgFile.m_ofn.Flags |= lFlags;
  32.  
  33.     CString strFilter;
  34.  
  35.     if (bOpenFileDialog)
  36.     {
  37.         strFilter += "Image Files (*.dds, *.hdr, *.bmp, *.tga, *.jpg, *.png, *.dib)";
  38.         strFilter += (TCHAR)'\0';   // next string please
  39.         strFilter += _T("*.dds;*.hdr;*.bmp;*.tga;*.jpg;*.png;*.dib");
  40.         strFilter += (TCHAR)'\0';   // last string
  41.         dlgFile.m_ofn.nMaxCustFilter++;
  42.     }
  43.     else
  44.     {
  45.         strFilter += "Image Files (*.dds)";
  46.         strFilter += (TCHAR)'\0';   // next string please
  47.         strFilter += _T("*.dds");
  48.         strFilter += (TCHAR)'\0';   // last string
  49.         dlgFile.m_ofn.nMaxCustFilter++;
  50.         dlgFile.m_ofn.lpstrDefExt = _T("dds"); // .dds is the default extension
  51.     }
  52.  
  53.     // append the "*.*" all files filter
  54.     CString allFilter;
  55.     VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
  56.     strFilter += allFilter;
  57.     strFilter += (TCHAR)'\0';   // next string please
  58.     strFilter += _T("*.*");
  59.     strFilter += (TCHAR)'\0';   // last string
  60.     dlgFile.m_ofn.nMaxCustFilter++;
  61.  
  62.     dlgFile.m_ofn.lpstrFilter = strFilter;
  63.     dlgFile.m_ofn.lpstrTitle = title;
  64.     dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
  65.  
  66.     INT_PTR nResult = dlgFile.DoModal();
  67.     fileName.ReleaseBuffer();
  68.     return nResult == IDOK;
  69. };
  70.  
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CDxTxCommandLineInfo
  74.  
  75. CDxtexCommandLineInfo::CDxtexCommandLineInfo(VOID)
  76. {
  77.     m_fmt = D3DFMT_UNKNOWN;
  78.     m_bAlphaComing = FALSE;
  79.     m_bMipMap = FALSE;
  80. }
  81.  
  82.  
  83. void CDxtexCommandLineInfo::ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast)
  84. {   
  85.     DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
  86.     if( CompareString( lcid, NORM_IGNORECASE, pszParam, -1, TEXT("DXT1"), -1 ) == CSTR_EQUAL )
  87.     {
  88.         m_fmt = D3DFMT_DXT1;
  89.     }
  90.     else if( CompareString( lcid, NORM_IGNORECASE, pszParam, -1, TEXT("DXT2"), -1 ) == CSTR_EQUAL )
  91.     {
  92.         m_fmt = D3DFMT_DXT2;
  93.     }
  94.     else if( CompareString( lcid, NORM_IGNORECASE, pszParam, -1, TEXT("DXT3"), -1 ) == CSTR_EQUAL )
  95.     {
  96.         m_fmt = D3DFMT_DXT3;
  97.     }
  98.     else if( CompareString( lcid, NORM_IGNORECASE, pszParam, -1, TEXT("DXT4"), -1 ) == CSTR_EQUAL )
  99.     {
  100.         m_fmt = D3DFMT_DXT4;
  101.     }
  102.     else if( CompareString( lcid, NORM_IGNORECASE, pszParam, -1, TEXT("DXT5"), -1 ) == CSTR_EQUAL )
  103.     {
  104.         m_fmt = D3DFMT_DXT5;
  105.     }
  106.     else if (bFlag && tolower(pszParam[0]) == 'a')
  107.     {
  108.         m_bAlphaComing = TRUE;
  109.     }
  110.     else if (!bFlag && m_bAlphaComing)
  111.     {
  112.         m_strFileNameAlpha = pszParam;
  113.         m_bAlphaComing = FALSE;
  114.     }
  115.     else if (bFlag && tolower(pszParam[0]) == 'm')
  116.     {
  117.         m_bMipMap = TRUE;
  118.     }
  119.     else if (!bFlag && !m_strFileName.IsEmpty())
  120.     {
  121.         m_strFileNameSave = pszParam;
  122.     }
  123.  
  124.     CCommandLineInfo::ParseParam(pszParam, bFlag, bLast);
  125. }
  126.  
  127.  
  128.  
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CDxtexApp
  131.  
  132. BEGIN_MESSAGE_MAP(CDxtexApp, CWinApp)
  133.     //{{AFX_MSG_MAP(CDxtexApp)
  134.     ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  135.         // NOTE - the ClassWizard will add and remove mapping macros here.
  136.         //    DO NOT EDIT what you see in these blocks of generated code!
  137.     //}}AFX_MSG_MAP
  138.     // Standard file based document commands
  139.     ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  140.     ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
  141. END_MESSAGE_MAP()
  142.  
  143. /////////////////////////////////////////////////////////////////////////////
  144. // CDxtexApp construction
  145.  
  146. CDxtexApp::CDxtexApp()
  147. {
  148.     // Place all significant initialization in InitInstance
  149.     m_pd3d = NULL;
  150.     m_pd3ddev = NULL;
  151.     m_bDeviceLost = FALSE;
  152. }
  153.  
  154. /////////////////////////////////////////////////////////////////////////////
  155. // CDxtexApp destruction
  156.  
  157. CDxtexApp::~CDxtexApp()
  158. {
  159.     ReleasePpo(&m_pd3ddev);
  160.     ReleasePpo(&m_pd3d);
  161. }
  162.  
  163. /////////////////////////////////////////////////////////////////////////////
  164. // The one and only CDxtexApp object
  165.  
  166. CDxtexApp theApp;
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169. // CDxtexApp initialization
  170.  
  171. BOOL CDxtexApp::InitInstance()
  172. {
  173.     // Change the registry key under which our settings are stored.
  174.     SetRegistryKey(_T("Microsoft"));
  175.  
  176.     LoadStdProfileSettings();  // Load standard INI file options (including MRU)
  177.  
  178.     // Register the application's document templates.  Document templates
  179.     //  serve as the connection between documents, frame windows and views.
  180.  
  181.     m_pDocManager = new CDxtexDocManager;
  182.     
  183.     CMultiDocTemplate* pDocTemplate;
  184.     pDocTemplate = new CMultiDocTemplate(
  185.         IDR_DXTXTYPE,
  186.         RUNTIME_CLASS(CDxtexDoc),
  187.         RUNTIME_CLASS(CChildFrame), // custom MDI child frame
  188.         RUNTIME_CLASS(CDxtexView));
  189.     AddDocTemplate(pDocTemplate);
  190.  
  191.     // Register file types with Explorer
  192.     RegisterShellFileTypes();
  193.     EnableShellOpen();
  194.  
  195.     // create main MDI Frame window
  196.     CMainFrame* pMainFrame = new CMainFrame;
  197.     if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
  198.         return FALSE;
  199.     m_pMainWnd = pMainFrame;
  200.  
  201.     // Initialize DirectDraw
  202.     m_pd3d = Direct3DCreate9(D3D_SDK_VERSION);
  203.     if (m_pd3d == NULL)
  204.     {
  205.         AfxMessageBox(ID_ERROR_D3DCREATEFAILED, MB_OK, 0);
  206.         return FALSE;
  207.     }
  208.  
  209.     HRESULT hr;
  210.     D3DPRESENT_PARAMETERS presentParams;
  211.     D3DDEVTYPE devType;
  212.  
  213.     ZeroMemory(&presentParams, sizeof(presentParams));
  214.     presentParams.Windowed = TRUE;
  215.     presentParams.SwapEffect = D3DSWAPEFFECT_COPY;
  216.     presentParams.BackBufferWidth = 8;
  217.     presentParams.BackBufferHeight = 8;
  218.     presentParams.BackBufferFormat = D3DFMT_UNKNOWN;
  219.  
  220.     devType = D3DDEVTYPE_REF; 
  221.  
  222.     hr = m_pd3d->CreateDevice(D3DADAPTER_DEFAULT, devType, m_pMainWnd->GetSafeHwnd(), 
  223.         D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParams, &m_pd3ddev);
  224.     if (FAILED(hr))
  225.     {
  226.         AfxMessageBox(ID_ERROR_CANTCREATEDEVICE);
  227.         return FALSE;
  228.     }
  229.  
  230.     D3DCAPS9 Caps;
  231.     m_pd3ddev->GetDeviceCaps(&Caps);
  232.     if (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE)
  233.     {
  234.         AfxMessageBox(ID_ERROR_NULLREF);
  235.     }
  236.  
  237.     // Parse command line for standard shell commands, DDE, file open
  238.     CDxtexCommandLineInfo cmdInfo;
  239.     ParseCommandLine(cmdInfo);
  240.     // Prevent automatic "New" at startup:
  241.     if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
  242.         cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
  243.  
  244.     // Dispatch commands specified on the command line
  245.     if (!ProcessShellCommand(cmdInfo))
  246.         return FALSE;
  247.  
  248.     // Enable open by dragging files
  249.     m_pMainWnd->DragAcceptFiles();
  250.  
  251.     // See if we loaded a document
  252.     POSITION posTemp = GetFirstDocTemplatePosition();
  253.     CDxtexDoc* pdoc = NULL;
  254.     POSITION pos = pDocTemplate->GetFirstDocPosition();
  255.     if (pos != NULL)
  256.         pdoc = (CDxtexDoc*)pDocTemplate->GetNextDoc(pos);
  257.  
  258.     if (!cmdInfo.m_strFileNameAlpha.IsEmpty())
  259.     {
  260.         if (pdoc != NULL)
  261.         {
  262.             pdoc->LoadAlphaBmp(cmdInfo.m_strFileNameAlpha);
  263.         }
  264.     }
  265.     if (cmdInfo.m_bMipMap)
  266.     {
  267.         if (pdoc != NULL)
  268.         {
  269.             pdoc->GenerateMipMaps();
  270.         }
  271.     }
  272.     if (cmdInfo.m_fmt != 0)
  273.     {
  274.         if (pdoc != NULL)
  275.         {
  276.             pdoc->Compress(cmdInfo.m_fmt, TRUE);
  277.         }
  278.     }
  279.     if (!cmdInfo.m_strFileNameSave.IsEmpty())
  280.     {
  281.         if (pdoc != NULL)
  282.         {
  283.             pdoc->OnSaveDocument(cmdInfo.m_strFileNameSave);
  284.         }
  285.         return FALSE; // Prevent UI from coming up
  286.     }
  287.  
  288.     // The main window has been initialized, so show and update it.
  289.     pMainFrame->ShowWindow(m_nCmdShow);
  290.     pMainFrame->UpdateWindow();
  291.  
  292.     return TRUE;
  293. }
  294.  
  295.  
  296. BOOL CDxtexApp::HandlePossibleLostDevice(VOID)
  297. {
  298.     HRESULT hr;
  299.  
  300.     if( !m_bDeviceLost )
  301.         return TRUE; // ok to render
  302.     
  303.     hr = m_pd3ddev->TestCooperativeLevel();
  304.  
  305.     if( hr == D3DERR_DEVICELOST )
  306.         return FALSE; // not ready to reset, but not ok to render
  307.  
  308.     if( hr == D3DERR_DEVICENOTRESET )
  309.     {
  310.         InvalidateDeviceObjects();
  311.         D3DPRESENT_PARAMETERS presentParams;
  312.  
  313.         ZeroMemory(&presentParams, sizeof(presentParams));
  314.         presentParams.Windowed = TRUE;
  315.         presentParams.SwapEffect = D3DSWAPEFFECT_COPY;
  316.         presentParams.BackBufferWidth = 8;
  317.         presentParams.BackBufferHeight = 8;
  318.         presentParams.BackBufferFormat = D3DFMT_UNKNOWN;
  319.         hr = m_pd3ddev->Reset( &presentParams );
  320.         if( FAILED( hr ) )
  321.             return FALSE;
  322.  
  323.         RestoreDeviceObjects();
  324.         m_bDeviceLost = FALSE;
  325.     }
  326.  
  327.     return TRUE;
  328. }
  329.  
  330.  
  331. HRESULT CDxtexApp::InvalidateDeviceObjects(VOID)
  332. {
  333.     // Tell each view of each doc to release its swap chains
  334.     POSITION pos = GetFirstDocTemplatePosition();
  335.     CDocTemplate* pDocTemplate = GetNextDocTemplate( pos );
  336.  
  337.     pos = pDocTemplate->GetFirstDocPosition();
  338.     for( ; ; )
  339.     {
  340.         CDocument* pDoc = NULL;
  341.         if( pos == NULL )
  342.             break;
  343.         pDoc = pDocTemplate->GetNextDoc( pos );
  344.         if( pDoc == NULL )
  345.             break;
  346.         POSITION posView;
  347.         CDxtexView* pView = NULL;
  348.         posView = pDoc->GetFirstViewPosition();
  349.         for( ; ; )
  350.         {
  351.             if( posView == NULL )
  352.                 break;
  353.             pView = (CDxtexView*)pDoc->GetNextView( posView );
  354.             if( pView == NULL )
  355.                 break;
  356.             pView->InvalidateDeviceObjects();
  357.         }
  358.     }
  359.     return S_OK;
  360. }
  361.  
  362.  
  363. HRESULT CDxtexApp::RestoreDeviceObjects(VOID)
  364. {
  365.     // Tell each view of each doc to restore
  366.     POSITION pos = GetFirstDocTemplatePosition();
  367.     CDocTemplate* pDocTemplate = GetNextDocTemplate( pos );
  368.  
  369.     pos = pDocTemplate->GetFirstDocPosition();
  370.     for( ; ; )
  371.     {
  372.         CDocument* pDoc = NULL;
  373.         if( pos == NULL )
  374.             break;
  375.         pDoc = pDocTemplate->GetNextDoc( pos );
  376.         if( pDoc == NULL )
  377.             break;
  378.         POSITION posView;
  379.         CDxtexView* pView = NULL;
  380.         posView = pDoc->GetFirstViewPosition();
  381.         for( ; ; )
  382.         {
  383.             if( posView == NULL )
  384.                 break;
  385.             pView = (CDxtexView*)pDoc->GetNextView( posView );
  386.             if( pView == NULL )
  387.                 break;
  388.             pView->RestoreDeviceObjects();
  389.         }
  390.     }
  391.     return S_OK;
  392. }
  393.  
  394.  
  395. /////////////////////////////////////////////////////////////////////////////
  396. // CAboutDlg dialog used for App About
  397.  
  398. class CAboutDlg : public CDialog
  399. {
  400. public:
  401.     CAboutDlg();
  402.  
  403. // Dialog Data
  404.     //{{AFX_DATA(CAboutDlg)
  405.     enum { IDD = IDD_ABOUTBOX };
  406.     CString m_strVersion;
  407.     //}}AFX_DATA
  408.  
  409.     // ClassWizard generated virtual function overrides
  410.     //{{AFX_VIRTUAL(CAboutDlg)
  411.     protected:
  412.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  413.     //}}AFX_VIRTUAL
  414.  
  415. // Implementation
  416. protected:
  417.     //{{AFX_MSG(CAboutDlg)
  418.         // No message handlers
  419.     //}}AFX_MSG
  420.     DECLARE_MESSAGE_MAP()
  421. };
  422.  
  423. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  424. {
  425.     TCHAR szFile[MAX_PATH];
  426.     CString strVersion;
  427.     UINT cb;
  428.     DWORD dwHandle;
  429.     BYTE FileVersionBuffer[2048];
  430.     VS_FIXEDFILEINFO* pVersion = NULL;
  431.  
  432.     GetModuleFileName(NULL, szFile, MAX_PATH);
  433.  
  434.     cb = GetFileVersionInfoSize(szFile, &dwHandle/*ignored*/);
  435.     if (cb > 0)
  436.     {
  437.         if (cb > sizeof(FileVersionBuffer))
  438.             cb = sizeof(FileVersionBuffer);
  439.  
  440.         ZeroMemory( FileVersionBuffer, sizeof(FileVersionBuffer) );
  441.         if (GetFileVersionInfo(szFile, 0, cb, FileVersionBuffer))
  442.         {
  443.             pVersion = NULL;
  444.             if (VerQueryValue(FileVersionBuffer, TEXT("\\"), (VOID**)&pVersion, &cb)
  445.                 && pVersion != NULL) 
  446.             {
  447.                 strVersion.Format("Version %d.%02d.%02d.%04d", 
  448.                     HIWORD(pVersion->dwFileVersionMS),
  449.                     LOWORD(pVersion->dwFileVersionMS), 
  450.                     HIWORD(pVersion->dwFileVersionLS), 
  451.                     LOWORD(pVersion->dwFileVersionLS));
  452.             }
  453.         }
  454.     }
  455.  
  456.     //{{AFX_DATA_INIT(CAboutDlg)
  457.     m_strVersion = strVersion;
  458.     //}}AFX_DATA_INIT
  459. }
  460.  
  461. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  462. {
  463.     CDialog::DoDataExchange(pDX);
  464.     //{{AFX_DATA_MAP(CAboutDlg)
  465.     DDX_Text(pDX, IDC_VERSION, m_strVersion);
  466.     //}}AFX_DATA_MAP
  467. }
  468.  
  469. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  470.     //{{AFX_MSG_MAP(CAboutDlg)
  471.         // No message handlers
  472.     //}}AFX_MSG_MAP
  473. END_MESSAGE_MAP()
  474.  
  475. // App command to run the dialog
  476. void CDxtexApp::OnAppAbout()
  477. {
  478.     CAboutDlg aboutDlg;
  479.     aboutDlg.DoModal();
  480. }
  481.